using UnityEngine;
using System.Collections;

namespace DanielSig.Geometry.Orbiter
{
	public abstract class Orbiter
	{
		public static explicit operator Vector2 (Orbiter orbiter)
		{
			return new Vector2 ((float)orbiter._dirX, (float)orbiter._dirY);
		}
		public static explicit operator Vector3 (Orbiter orbiter)
		{
			return new Vector3 ((float)orbiter._dirX, (float)orbiter._dirY, 0);
		}
		public static explicit operator int (Orbiter orbiter)
		{
			return orbiter._iterations;
		}
		
		public static Orbiter operator ++ (Orbiter orbiter)
		{
			orbiter.NextAndUpdate ();
			return orbiter;
		}
		public static Orbiter operator + (Orbiter orbiter, int iterations)
		{
			orbiter = orbiter.Copy ();
			if (iterations > 0) {
				for (int i = 0; i < iterations; i++) {
					orbiter.QuickNext ();
				}
			}
			else {
				for (int i = 0; i > iterations; i--) {
					orbiter.QuickPrevious ();
				}
			}
			orbiter._iterations += iterations;
			orbiter.Update ();
			return orbiter;
		}
		public static bool operator == (Orbiter lhs, Orbiter rhs)
		{
			return lhs._iterations == rhs._iterations;
		}
		public static bool operator != (Orbiter lhs, Orbiter rhs)
		{
			return lhs._iterations != rhs._iterations;
		}
		public static bool operator == (Orbiter lhs, object rhs)
		{
			return lhs._iterations == (int)rhs;
		}
		public static bool operator != (Orbiter lhs, object rhs)
		{
			return lhs._iterations != (int)rhs;
		}
		public static bool operator < (Orbiter lhs, object rhs)
		{
			return lhs._iterations < (int)rhs;
		}
		public static bool operator > (Orbiter lhs, object rhs)
		{
			return lhs._iterations > (int)rhs;
		}
		
		public float cycles {
			get { return (float)(_iterations * angleSpeed * 0.002777777777777777D); }
		}
		public float angle{
			get{ return _iterations * angleSpeed; }
		}
		public float angleSpeed {
			get { return _angleSpeed; }
		}
		public Vector2 direction {
			get { return new Vector2((float)_dirX, (float)_dirY); }
		}
		
		public virtual float x {
			get { return (float)_dirX; }
		}
		public virtual float y {
			get { return (float)_dirY; }
		}
		public virtual double xDouble {
			get { return _dirX; }
		}
		public virtual double yDouble {
			get { return _dirY; }
		}
		
		
		public Orbiter ()
		{
			_angleSpeed = 45F;
			_gravity = 1;
			_iterations = 0;
		}
		
		public abstract Orbiter Copy ();
		
		public abstract void Update();
		public abstract void Next ();
		public abstract void Previous ();
		public abstract void NextAndUpdate ();
		public abstract void PreviousAndUpdate ();
		
		public override bool Equals (object o)
		{
			return _iterations == (int)o;
		}
		public override int GetHashCode ()
		{
			return _iterations;
		}
		
		protected int _iterations;
		protected float _angleSpeed;
		protected double _gravity;
		
		protected double _velX;
		protected double _velY;
		
		protected double _dirX;
		protected double _dirY;
		
		protected abstract void QuickNext ();
		protected abstract void QuickPrevious ();
		
		protected virtual void InitOrbiter ()
		{
			_angleSpeed = Mathf.Clamp (_angleSpeed, -180, 180);
		}
	}
}